package com.atguigu.gmall.item.service;

import com.atguigu.core.bean.Resp;
import com.atguigu.gmall.item.fegin.GmallPmsClient;
import com.atguigu.gmall.item.fegin.GmallSmsClient;
import com.atguigu.gmall.item.fegin.GmallWmsClient;
import com.atguigu.gmall.item.vo.ItemVO;
import com.atguigu.gmall.pms.entity.*;
import com.atguigu.gmall.pms.vo.ItemGroupVO;
import com.atguigu.gmall.sms.vo.ItemSkuSaleVO;
import com.atguigu.gmall.wms.entity.WareSkuEntity;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;

import static java.util.concurrent.CompletableFuture.supplyAsync;

/**
 * 同步：fegin的调用
 * 异步：子线程（多线程的子线程来调用）
 * 编排：控制，控制线程在什么时候执行，之前的new runable不好控制
 *
 *
 */
@Service
public class ItemService {

    @Autowired
    private GmallPmsClient pmsClient;

    @Autowired
    private GmallWmsClient wmsClient;
    @Autowired
    private GmallSmsClient smsClient;

    @Autowired
    private ThreadPoolExecutor threadPoolExecutor;//线程池

    public ItemVO queryItemVo(Long skuId) {

        ItemVO itemVO=new ItemVO();
        //0\设置skuId
        itemVO.setSkuId(skuId);
        //1、根据skuId查询sku
        //因为所有的下面查询都依赖于skuid
        // 获取sku的基本信息
        // 后续获取sku的促销信息、spu的销售属性和spu详情信息（需要sku中的spuId）都需要skuInfoEntity
        // supplyAsync有返回值
        // runAsync无返回值
        // 所以这里需要使用supplyAsync
        CompletableFuture<Object> completableFuture=CompletableFuture.supplyAsync(()->{
            Resp<SkuInfoEntity> skuInfoEntityResp = this.pmsClient.querySkuBySkuId(skuId);
            SkuInfoEntity skuInfoEntity = skuInfoEntityResp.getData();
            if(skuInfoEntity==null){
                return itemVO;
            }
//            itemVO.setSkuTitle(skuInfoEntity.getSkuTitle());
//            itemVO.setSubTitle(skuInfoEntity.getSkuSubtitle());
//            itemVO.setPrice(skuInfoEntity.getPrice());
//            itemVO.setWeight(skuInfoEntity.getWeight());
//            itemVO.setSpuId(skuInfoEntity.getSpuId());
            BeanUtils.copyProperties(skuInfoEntity, itemVO);
            return skuInfoEntity;//返回对象，后面还得获取品牌id
        },threadPoolExecutor);

//        CompletableFuture<SkuInfoEntity> skuFuture = CompletableFuture.supplyAsync(() -> {
////            Resp<SkuInfoEntity> skuInfoEntityResp = this.pmsFeign.querySkuById(skuId);
////            SkuInfoEntity skuInfoEntity = skuInfoEntityResp.getData();
////            if (skuInfoEntity != null) {
////                BeanUtils.copyProperties(skuInfoEntity, itemVO);
////            }
////            return skuInfoEntity;
//
//        }, threadPoolExecutor);
        //2\根据sku中的spuId查询spu
        //spu依赖于sku的
        CompletableFuture<Void> spuCompletableFuture = completableFuture.thenAcceptAsync(sku -> {

            Resp<SpuInfoEntity> spuInfoEntityResp = this.pmsClient.querySpuById(((SkuInfoEntity) sku).getSpuId());
            SpuInfoEntity spuInfoEntity = spuInfoEntityResp.getData();

            if (spuInfoEntity != null) {
                itemVO.setSpuName(spuInfoEntity.getSpuName());
            }
        }, threadPoolExecutor);//匿名内部类开启一个任务

        //3\根据skuId查询图片列表
        //重新开一个线程池，不依赖上面的
        CompletableFuture<Void> imageCompletableFuture = CompletableFuture.runAsync(() -> {

            Resp<List<SkuImagesEntity>> skuImagesResp = this.pmsClient.querySkuImagesBySkuId(skuId);
            List<SkuImagesEntity> imagesEntities = skuImagesResp.getData();
            itemVO.setPics(imagesEntities);//这个地方不需要判断，是因为是对象，不会出现空指针异常
        }, threadPoolExecutor);

        //4\根据sku的brand和category设置品牌和分类
        CompletableFuture<Void> cateCompletableFuture = completableFuture.thenAcceptAsync(sku -> {
            Resp<CategoryEntity> categoryEntityResp = this.pmsClient.queryCategoryById(((SkuInfoEntity) sku).getCatalogId());
            CategoryEntity categoryEntity = categoryEntityResp.getData();
            itemVO.setCategoryEntity(categoryEntity);
        }, threadPoolExecutor);
        CompletableFuture<Void> brandCompletableFuture = completableFuture.thenAcceptAsync(sku -> {
            Resp<BrandEntity> brandEntityResp = this.pmsClient.queryBrandById(((SkuInfoEntity) sku).getBrandId());
            BrandEntity brandEntity = brandEntityResp.getData();
            itemVO.setBrandEntity(brandEntity);
        }, threadPoolExecutor);

        //5\根据skuId查询营销信息
        CompletableFuture<Void> saleqCompletableFuture = CompletableFuture.runAsync(() -> {
            Resp<List<ItemSkuSaleVO>> saleResp = this.smsClient.querySkuSaleBySkuId(skuId);
            List<ItemSkuSaleVO> saleVOS = saleResp.getData();
            itemVO.setSales(saleVOS);
        }, threadPoolExecutor);


        //6\根据skuId查询库存信息
        CompletableFuture<Void> wareCompletableFuture = CompletableFuture.runAsync(() -> {
            Resp<List<WareSkuEntity>> wareSkuBySkuId = this.wmsClient.queryWareSkuBySkuId(skuId);
            List<WareSkuEntity> wareSkuEntities = wareSkuBySkuId.getData();
            itemVO.setStore(wareSkuEntities.stream().anyMatch(wareSkuEntity -> wareSkuEntity.getStock() > 0));//库存只要有一个大于0，就代表有货
        }, threadPoolExecutor);


        //7\根据spuId查询所有的skuIds,再去查询所有的销售属性
        CompletableFuture<Void> saleAttrCompletableFuture = completableFuture.thenAcceptAsync(sku -> {
            Resp<List<SkuSaleAttrValueEntity>> listResp = this.pmsClient.querySkuSaleAttrValueBySpuId(((SkuInfoEntity) sku).getSpuId());
            List<SkuSaleAttrValueEntity> skuSaleAttrValueEntities = listResp.getData();
            itemVO.setSaleAttrValueEntityList(skuSaleAttrValueEntities);
        }, threadPoolExecutor);


        //8\根据spuId查询商品描述（海报）
        CompletableFuture<Void> descCompletableFuture = completableFuture.thenAcceptAsync(sku -> {
            Resp<SpuInfoDescEntity> spuInfoDescEntityResp = this.pmsClient.querySpuDescBySpuId(((SkuInfoEntity) sku).getSpuId());
            SpuInfoDescEntity spuInfoDesc = spuInfoDescEntityResp.getData();
            if (spuInfoDesc != null) {
                String decript = spuInfoDesc.getDecript();
                String[] split = StringUtils.split(decript, ",");
                itemVO.setImages(Arrays.asList(split));
            }
        }, threadPoolExecutor);


        //9\根据spuId和cateId查询组及组下的spu的规格参数，不是attr的实体是productAttr
        CompletableFuture<Void> groupCompletableFuture = completableFuture.thenAcceptAsync(sku -> {
            Resp<List<ItemGroupVO>> itemGroupVOByCidAndSpuId = this.pmsClient.queryItemGroupVOByCidAndSpuId(((SkuInfoEntity) sku).getCatalogId(), ((SkuInfoEntity) sku).getSpuId());
            List<ItemGroupVO> groupVOS = itemGroupVOByCidAndSpuId.getData();
            itemVO.setGroups(groupVOS);
        }, threadPoolExecutor);

        //不能直接return，需要阻塞一下，等待所有任务完成

        CompletableFuture.allOf(spuCompletableFuture,imageCompletableFuture,cateCompletableFuture,
                brandCompletableFuture,saleqCompletableFuture,wareCompletableFuture,saleAttrCompletableFuture
        ,descCompletableFuture,groupCompletableFuture).join();
        return itemVO;
    }
}
